<?php
/**
 * User: wanghousheng
 * Date: 2017/6/14
 * Time: 14:32
 * QQ登录
 * 备注 pc wap 实例化对象传回调函数地址(BACKURL)绝对路径 首先调用login() 在回调函数中调用getUsrInfo()方法
 * app 实例化对象 不用传回调函数地址 直接调用getUsrInfo()但必须传accessToken tyepe=app
 */

class Qqoauth
{
    const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
    const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";
    const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";
    const GET_USER_INFO = "https://graph.qq.com/user/get_user_info";
    const GET_USER_INFO_APP = "https://openmobile.qq.com/user/get_simple_userinfo";
    public $apiId;
    public $apiKey;
    public $callBackUrl;
    public $code;
    public function __construct($params=array()){
        if (isset($params['APIId']) && $params['APIId']){
            $this->apiId = $params['APIId'];
        }else{
            $this->apiId = '';
        }
        if (isset($params['APIKEY']) && $params['APIKEY']){
            $this->apiKey = $params['APIKEY'];
        }else{
            $this->apiKey = '';
        }
        if (isset($params['BACKURL']) && $params['BACKURL']){
            $this->callBackUrl = $params['BACKURL'];
        }else{
            $this->callBackUrl = '';
        }
        $this->code = isset($_REQUEST['code'])? $_REQUEST['code'] : '';

    }
    /**
     * Name: pc wap登录
     * User: wanghousheng
     * Date: 2017/6/14
     * @param string $state(自定义值)
     * @param string $display(pc mobile)
     * @return string
     */
    public function login($state='',$display=''){
        if (empty($this->callBackUrl)){
            return $this->ApiState(false,'回调地址不能为空');
        }
        if (!$state) $state = md5(uniqid(rand(), TRUE));
        $params['response_type']="code";
        $params['client_id']=$this->app_id;
        $params['redirect_uri']=$this->callBackUrl;
        $params['display'] = $display;
        $params['state']=$state;
        $params['scope']="get_user_info";
        $param =http_build_query($params,'','&');
        $login_url=self::GET_AUTH_CODE_URL."?".$param;
        $this->ApiState(true,'success',array('login_url'=>$login_url));
    }
    /**
     * Name: 通过Authorization Code获取Access Token
     * User: wanghousheng
     * Date: 2017/6/14
     * @return mixed
     */
    public function getAccessToken(){
        $param['grant_type']="authorization_code";
        $param['client_id']=$this->apiId;
        $param['client_secret']=$this->apiKey;
        $param['code']=$this->code;
        $param['redirect_uri']=$this->callBackUrl;
        $param =http_build_query($param,'','&');
        $url=self::GET_ACCESS_TOKEN_URL."?".$param;
        $response = $this->getUrl($url);
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }
        $params = array();
        parse_str($response, $params);
        return $params["access_token"];
    }

    /**
     * Name: 获取openid
     * User: wanghousheng
     * Date: 2017/6/14
     * @param $accessToken
     * @return array
     */
    public function getOpenID($accessToken){
        if (empty($accessToken)){
            $accessToken=$this->getAccessToken();
        }
        $param['access_token']=$accessToken;
        $param['unionid'] = 1;
        $param =http_build_query($param,'','&');
        $url=self::GET_OPENID_URL."?".$param;
        $response=$this->getUrl($url);
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }
        $res = json_decode($response,true);
        if (!isset($res['openid']) || !isset($res['unionid'])){
            return $this->ApiState(false,'获取openid错误',$res);
        }
        if ($res['openid']){
            $return['openid'] = $res['openid'];
        }
        if ($res['unionid']){
            $return['unionid'] = $res['unionid'];
        }
        $return['accessToken'] = $accessToken;
        return $return;
    }

    /**
     * Name: app获取openid
     * User: wanghousheng
     * Date: 2016/12/27
     * @param $token
     * @return mixed
     */
    public function get_openid($token,$get_unioid=false){
        $keysArr = array(
            "access_token" => $token,
        );
        if ($get_unioid) $keysArr['unionid'] = 1;
        $graph_url = $this->combine_url(self::GET_OPENID_URL, $keysArr);
        $response = $this->getUrl($graph_url);
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }
        $user = json_decode($response, true);
        return $user;
    }

    private function combine_url($baseURL,$keysArr){
        $combined = $baseURL."?";
        $valueArr = array();
        foreach($keysArr as $key => $val){
            $valueArr[] = "$key=$val";
        }
        $keyStr = implode("&",$valueArr);
        $combined .= ($keyStr);
        return $combined;
    }
    /**
     * Name: 获取用户信息
     * User: wanghousheng
     * Date: 2017/6/14
     * @param string $accessToken
     * @param string $type
     * @return array|mixed
     */
    public function getUsrInfo($accessToken,$openid ='',$type=''){
        if(empty($openid)){
            $res=$this->getOpenID($accessToken);
            if(!isset($res['openid']) || empty($res['openid'])){
                return $this->ApiState(false,'openid错误');
            }
            $openid = $res['openid'];
            $accessToken = $res['accessToken'];
        }
        $param['access_token']=$accessToken;
        $param['oauth_consumer_key']=$this->apiId;
        $param['openid'] = $openid;
        $param =http_build_query($param,'','&');
        $url=self::GET_USER_INFO."?".$param;
        if ($type && $type='app'){
            $url=self::GET_USER_INFO_APP."?".$param;
        }
        $rzt=$this->getUrl($url);
        $rzt = json_decode($rzt,true);
        $rzt['unionid'] = $res['unionid'];
        $rzt['openid'] =$openid;
        return $rzt;
    }
    //CURL GET
    private function getUrl($url){
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        if (!empty($options)){
            curl_setopt_array($ch, $options);
        }
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
    /**
     * Name: 返回状态
     * User: wanghousheng
     * Date: 2017/6/14
     * @param bool $status
     * @param string $msg
     * @param array $data
     * @return array
     */
    private function ApiState($status = true,$msg = 'success',$data = array()){
        return array('status'=>$status,'message'=>$msg,'data'=>$data);
    }
}